home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 4
/
Aminet 4 - November 1994.iso
/
aminet
/
comm
/
net
/
amipop112.lha
/
AmiPOP112
/
source
/
pop_dopop.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-09
|
9KB
|
579 lines
#include "pop.h"
/* Stuff for "From " Header */
/* Courtesy Michael B. Smith */
struct mytm {
int year;
int month;
int day;
int dow;
int hour;
int min;
int sec;
};
/* DaysInMonth */
static const int dim [] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
static const char *months [] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
static const char *days [] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
static void DateStampToMyTm (struct DateStamp *date, struct mytm *da)
{
int days, years, leap = 0, month = 0;
days = date->ds_Days + 731; /* 1976 */
years = days / (365*3+366); /* #quad yrs */
days -= years * (365*3+366);
years = 1976 + 4 * years;
if (days <= 365)
{
leap = 1;
}
else
{
days -= 366;
++years;
years += days / 365;
days %= 365;
}
month = 0;
while (1)
{
if (month == 1)
{
if (days < (28 + leap)) break;
days -= 28 + leap;
}
else
{
if (days < dim [month]) break;
days -= dim [month];
}
++month;
}
da->hour = date->ds_Minute / 60;
da->min = date->ds_Minute % 60;
da->sec = date->ds_Tick / 50;
da->day = days + 1;
da->month = month + 1;
da->dow = date->ds_Days % 7; /* 0 = sunday */
da->year = years;
return;
}
char * datestr (char *buf)
{
/*
** datestr
**
** Build ARPA date-time as specified in RFC-822:
**
** Wed, 13 Oct 93 18:52:04 EST
** 123456789012345678901234567890
**
** buf must be 24 characters, plus space for TimeZone and NUL.
**
** As TimeZone may be "(+23:30)" or similar, 33 chars should
** do it.
*/
struct mytm da;
struct DateStamp ds;
DateStampToMyTm (DateStamp (&ds), &da);
DoFmt (buf, "%s, %ld %s %ld %02ld:%02ld:%02ld",
days [da.dow], da.day,
months [da.month - 1], da.year % 100,
da.hour, da.min, da.sec);
return buf;
}
char * time_stamp (char *buf)
{
/*
** time_stamp
**
** Put a time/date stamp into buf (for logging)
**
** 13 Nov 93 13:14:45
*/
struct DateStamp ds;
struct mytm da;
DateStampToMyTm (DateStamp (&ds), &da);
DoFmt (buf, "%ld %s %ld %02ld:%02ld:%02ld",
da.day,
months [da.month - 1], da.year % 100,
da.hour, da.min, da.sec);
return buf;
}
/* End stuff for "From " header */
#define ASYNCBUFSIZE 8192
BOOL needfrom ( char * , struct AsyncFile *);
/* Variables global to this file */
struct Library *SockBase ;
int havemail;
/* Functions */
int dopop(void)
{
int s;
int count;
int okay=1;
struct hostent *hp;
struct sockaddr_in sa;
DoFmt(title,"Connecting to %s",pophost);
settitle(title);
if((SockBase = OpenLibrary( SOCKLIBNAME, SOCKLIBVERSION )) == NULL)
{
doreq("Error opening socket.library\n",bum);
return(1);
}
#ifdef AMITCP
SetErrnoPtr(&errno, sizeof errno);
#else
setup_sockets( MAXSOCKS, &errno );
#endif
if((hp=gethostbyname(pophost))==NULL)
{
#ifndef AMITCP
cleanup_sockets();
#endif
CloseLibrary( SockBase ) ;
doreq("Connection Refused.",bum);
return(1);
}
bzero(&sa, sizeof(sa));
bcopy(hp->h_addr, (char *)&sa.sin_addr, hp->h_length);
sa.sin_family = hp->h_addrtype;
sa.sin_port = htons((u_short)port);
if ((s=socket(hp->h_addrtype,SOCK_STREAM,0)) < 0)
{
#ifndef AMITCP
cleanup_sockets();
#endif
CloseLibrary( SockBase ) ;
doreq("Something bad\nhas happened.",bum);
return(1);
}
if (connect(s,(struct sockaddr *) &sa,sizeof(sa))< 0)
{
doreq("No POP3 daemon\nrunning on this\nmachine or port.",bum);
s_close(s);
#ifndef AMITCP
cleanup_sockets();
#endif
CloseLibrary( SockBase ) ;
return(1);
}
/* Put actual code here */
recv(s,buf,BUFSIZE-1,0);
settitle("Got Connection");
sendgreet(s);
if (senduser(s))
{
#ifndef AMITCP
cleanup_sockets();
#endif
CloseLibrary( SockBase ) ;
return(1);
}
count=havemail=sendstat(s);
while (count && okay)
{
DoFmt(title,"Retrieving %lu",count);
settitle(title);
okay=retrieve(s,count);
if (delmail && okay)
{
DoFmt(title,"Deleting %lu",count);
settitle(title);
okay=delmessage(s,count);
}
--count;
}
if(sendquit(s))
{
#ifndef AMITCP
cleanup_sockets();
#endif
CloseLibrary( SockBase ) ;
return(1);
}
if (Project0Wnd)
{
SetWindowTitles(Project0Wnd,Project0Wdt, (UBYTE *) ~0);
}
if (havemail && notify) /* removed sendstat() after Nofify */
{
doreq("You have new mail.","Cool");
}
/* End actual code */
s_close(s);
#ifndef AMITCP
cleanup_sockets();
#endif
CloseLibrary( SockBase ) ;
return(0);
}
int sendgreet(int s)
{
DoFmt(buf,"HELLO\r\n");
trans(s,buf);
return(0);
}
int senduser(int s)
{
int t;
settitle("Sending Username");
DoFmt(buf,"USER %s\r\n",username);
if ( !trans(s,buf) ) return(1);
t=sscanf(buf,"%s",temp);
if ( valcheck(t,temp) ) return(1);
/* Password */
settitle("Sending Password");
DoFmt(buf,"PASS %s\r\n",password);
if ( !trans(s,buf) ) return(1);
t=sscanf(buf,"%s",temp);
if ( valcheck(t,temp) ) return(1);
return(0);
}
int sendquit(int s)
{
int t;
settitle("Sending QUIT");
DoFmt(buf,"QUIT\r\n");
if ( !trans(s,buf) ) return(1);
t=sscanf(buf,"%s",temp);
if ( valcheck(t,temp) ) return(1);
settitle("Quit Acknowledged");
return(0);
}
int sendstat( int s )
{
int t;
int count=0;
DoFmt(buf,"STAT\r\n");
if ( !trans(s,buf) ) return(0);
t=sscanf(buf,"%s %lu",temp,&count);
if ( valcheck(t,temp) ) return(0);
return(count);
}
int retrieve(int s,int count)
{
int foo;
int c;
int goon=1;
char *havefrom;
char *buf2;
char *buf3;
BOOL begin=TRUE;
struct AsyncFile *ofp;
if (havefrom=AllocVec(512,MEMF_CLEAR))
{
if ( (count == havemail) && (!appfile) )
{
ofp = OpenAsync(maildir, MODE_WRITE,ASYNCBUFSIZE);
}
else
{
ofp = OpenAsync(maildir, MODE_APPEND,ASYNCBUFSIZE);
}
if ( ofp == NULL)
{
doreq("Open() failed\n",bum);
FreeVec(havefrom);
return(0);
}
DoFmt(buf,"RETR %lu\r\n",count);
if ( !trans(s,buf) )
{
CloseAsync(ofp);
FreeVec(havefrom);
return(0);
}
if ( valcheck(1,buf) )
{
CloseAsync(ofp);
FreeVec(havefrom);
return(0);
}
buf3=strstr(buf,"\r\n");
if ( (buf3) && (buf3+2) )
{
char *buf4;
if (needfrom(buf3,ofp))
{
begin=FALSE;
}
buf4=strip(buf3);
buf3=stpchrn(buf4,0x20);
if (buf3)
{
WriteAsync(ofp,buf3,strlen(buf3));
}
}
while ( goon )
{
foo=recv(s,buf,BUFSIZE-1,0);
if (foo < 1)
{
goon=0;
}
buf[foo]='\0';
goon=lastblock(buf);
/* Magic to add "From " header */
if (begin && goon)
{
needfrom(buf,ofp);
}
begin=FALSE;
buf2=strip(buf);
c=WriteAsync(ofp,buf2,strlen(buf2));
if (c == -1)
{
doreq("FPuts() failed!",bum);
goon=0;
}
}
WriteAsync(ofp,"\n",1);
CloseAsync(ofp);
FreeVec(havefrom);
return(1);
}
else
{
return(0);
}
}
int delmessage( int s, int count )
{
DoFmt(buf,"DELE %lu\r\n",count);
trans(s,buf);
if ( valcheck(1,buf) ) return(0);
return(1);
}
int valcheck(int t, char *localtemp)
{
if (t == 0)
{
doreq("scanf() failed\n",bum);
return(1);
}
if ( !strstr(localtemp,"+OK") )
{
doreq("Didn't get +OK",bum);
if (localtemp[0] != '\0')
{
doreq(localtemp,bum);
}
return(1);
}
return(0);
}
int trans( int s, char *mybuf )
{
int foo;
send(s,mybuf,strlen(mybuf),0);
foo=recv(s,buf,BUFSIZE-1,0);
if ( foo < 1 )
{
return(0);
}
buf[foo]='\0';
return (1);
}
void settitle( char *newtitle )
{
if (winop)
{
SetWindowTitles(Project0Wnd,newtitle, (UBYTE *) ~0);
}
}
char *strip( char *mybuf )
{
char out[BUFSIZE]="";
ULONG x1=0;
ULONG x2=0;
ULONG len;
len=strlen(mybuf);
while (mybuf[x1] != '\0' )
{
while (mybuf[x1] == '\r')
{
++x1;
}
out[x2]=mybuf[x1];
++x2;
if (x1 < len)
{
++x1;
}
}
out[x2]='\0';
strcpy(mybuf,out);
return(mybuf);
}
int lastblock (char *segment)
{
char *found;
int len = strlen(segment);
if ( (found=strstr(segment,"\r\n.\r\n")))
{
/*buf[found-segment]='\n';*/
buf[found-segment]='\0'; /* used to be found-segment+2 */
return(0);
}
if ( (len==2) && (found=strstr(segment,"\r\n")) )
{
buf[found-segment]='\0'; /* Added recently */
return(0);
}
if ( len==1 ) /* Kludge of the century */
{
return(0);
}
if ( (len <= 4) && (found=strstr(segment,".\r\n")) )
{
/*buf[found-segment]='\n';*/
buf[found-segment]='\0';
return(0);
}
return(1);
}
BOOL needfrom(char *mybuf,struct AsyncFile *ofp)
{
if ( !strstr(mybuf,"From ") )
{
char *newtemp;
if (newtemp=AllocVec(BIGSTRING,MEMF_CLEAR))
{
int tempsize=0;
DoFmt(newtemp,"From %s@%s ", username,pophost);
tempsize=strlen(newtemp);
DoFmt((newtemp+tempsize),"%s\n",datestr((newtemp+tempsize)));
WriteAsync(ofp,newtemp,strlen(newtemp));
FreeVec(newtemp);
}
return(TRUE);
}
return(FALSE);
}